package me.firstapp.weixin.controller.pay;

import java.io.IOException;
import java.io.InputStream;
import java.math.RoundingMode;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSONObject;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.weixin.XmlResult;
import com.foxinmy.weixin4j.mp.WeixinProxy;
import com.foxinmy.weixin4j.mp.api.NotifyApi;
import com.foxinmy.weixin4j.mp.api.TmplApi;
import com.foxinmy.weixin4j.mp.message.NotifyMessage;
import com.foxinmy.weixin4j.mp.message.TemplateMessage;
import com.foxinmy.weixin4j.payment.mch.MchPayRequest;
import com.foxinmy.weixin4j.payment.mch.Order;
import com.foxinmy.weixin4j.tuple.Text;
import com.foxinmy.weixin4j.type.IdQuery;
import com.foxinmy.weixin4j.type.IdType;
import com.foxinmy.weixin4j.type.TradeState;
import com.foxinmy.weixin4j.util.Consts;
import com.foxinmy.weixin4j.util.IOUtil;
import com.foxinmy.weixin4j.util.StringUtil;
import com.foxinmy.weixin4j.xml.ListsuffixResultDeserializer;
import com.foxinmy.weixin4j.xml.XmlStream;

import me.firstapp.common.exception.ServiceException;
import me.firstapp.common.utils.DateUtils;
import me.firstapp.common.utils.HttpUtils;
import me.firstapp.common.utils.SystemConfig;
import me.firstapp.common.utils.WeiXinConfig;
import me.firstapp.module.weixin.member.Member;
import me.firstapp.module.weixin.member.PaymentRecord;
import me.firstapp.module.weixin.order.SoftOrder;
import me.firstapp.service.weixin.member.MemberService;
import me.firstapp.service.weixin.soft.SoftOrderService;
import me.firstapp.weixin.controller.base.BaseController;
import me.firstapp.weixin.utils.WchatConfig;

@Controller
public class PayController extends BaseController {

	private Logger logger = LoggerFactory.getLogger(PayController.class);

	@Autowired
	private SoftOrderService softOrderService;

	@Autowired
	private WeixinProxy weixinProxy;

	@Autowired
	private MemberService memberService;

	/**
	 * 微信支付页面
	 * 
	 * @param orderNo
	 * @param request
	 * @param response
	 * @param modelMap
	 * @return
	 * @throws WeixinException
	 * @throws IOException
	 */
	@RequestMapping("/page/wxPayPage.htm")
	public ModelAndView wxPayPage(String orderNo, String remark, HttpServletRequest request,
			HttpServletResponse response, ModelMap modelMap) throws WeixinException, IOException {
		System.out.println("**********微信支付，订单号：" + orderNo);
		String openId = getCurrentLoginOpenId(request, response);
		double payFee = 0.01;// 支付金额最低为1分钱
		String body = "";

		String orderType = orderNo.substring(0, 1);
		if (SoftOrder.ORDER_NO_START.equals(orderType)) {
			SoftOrder softOrder = softOrderService.findByOrderNo(orderNo);
			if (SoftOrder.STATUS_NOT_PAY != softOrder.getStatus()) {
				throw new ServiceException("error", "订单状态异常");
			}
			payFee = softOrder.getPayAmount().setScale(2, RoundingMode.HALF_UP).doubleValue();
			body = "服务费";
		}
		MchPayRequest payRequest = WchatConfig.getInstance().getWeixinPayProxy().createJSPayRequest(openId, body,
				orderNo, payFee, WeiXinConfig.WEIXIN_NOTIFY_URL, HttpUtils.getIpAddress(request), "");
		System.out.println("订单号" + orderNo + "微信支付结果：" + JSONObject.toJSONString(payRequest));
		System.out.println("jspay:" + payRequest.toRequestString());
		modelMap.put("jspay", payRequest.toRequestString());
		modelMap.put("orderNo", orderNo);
		return new ModelAndView("pay/wxPayment", modelMap);
	}

	/**
	 * 微信支付成功(前端)时的回调通知
	 */
	@RequestMapping("/page/paySuccess.htm")
	public ModelAndView paySuccess(String orderNo, HttpServletRequest request, HttpServletResponse response,
			ModelMap modelMap) {
		getCurrentLoginOpenId(request, response);
		return new ModelAndView("pay/paySuccess", modelMap);
	}

	/**
	 * 微信支付成功 后端回调通知
	 */
	@RequestMapping("/wxPayNotify.do")
	@ResponseBody
	public String wxPayNotify(InputStream input) throws IOException, WeixinException {
		String content = StringUtil.newStringUtf8(IOUtil.toByteArray(input));
		Order order = ListsuffixResultDeserializer.deserialize(content, Order.class);
		Order wxOrder = WchatConfig.getInstance().getWeixinPayProxy()
				.queryOrder(new IdQuery(order.getOutTradeNo(), IdType.TRADENO));
		logger.info("微信支付回调通知----->order订单信息，" + wxOrder.toString());
		logger.info("微信支付回调通知----->wxOrder订单信息，" + wxOrder.toString());
		if (TradeState.SUCCESS.toString().equals(wxOrder.getReturnCode())
				&& TradeState.SUCCESS.toString().equals(wxOrder.getResultCode())
				&& TradeState.SUCCESS.toString().equals(wxOrder.getTradeState())) {
			String orderNo = wxOrder.getOutTradeNo();
			String orderType = orderNo.substring(0, 1);
			if (SoftOrder.ORDER_NO_START.equals(orderType)) {

				SoftOrder softOrder = softOrderService.findByOrderNo(orderNo);
				if (SoftOrder.STATUS_NOT_PAY != softOrder.getStatus()) {
					logger.error("订单【" + softOrder.getOrderNo() + "】未处于未支付状态！");
					return null;
				}

				softOrderService.executeConfirmOrder(softOrder);
				if (SoftOrder.STATUS_PAYED == softOrder.getStatus()) {
					softOrderService.executeSavePaymentRecord(softOrder, "", PaymentRecord.STATUS_SUCCESS, "", "");
					try {
						String text = "尊敬的用户，您申请的【" + getVipName(softOrder.getVipLevel()) + "服务】付款成功，申请编号【"
								+ softOrder.getOrderNo() + "】";

						String openId = softOrder.getOpenId();
						NotifyApi notifyApi = new NotifyApi(weixinProxy.getTokenManager());
						notifyApi.sendNotify(new NotifyMessage(openId, new Text(text)));
					} catch (WeixinException e1) {
						e1.printStackTrace();
					}
				}

				Member member = memberService.findMemberByOpenId(softOrder.getOpenId());
				String oldVipStr = getVipName(member.getVipLevel());
				String newVipStr = getVipName(softOrder.getVipLevel());

				softOrder = softOrderService.executeCompleteOrder(softOrder);
				if (SoftOrder.STATUS_COMPLETE == softOrder.getStatus()) {
					try {
						TemplateMessage tplMessage = new TemplateMessage(softOrder.getOpenId(),
								WeiXinConfig.WEIXIN_LEVEL_CHANGE_TEMPLATE_ID,
								SystemConfig.mServerUrl + "/page/memberCenterPage.htm");
						member = null;
						member = memberService.findMemberByOpenId(softOrder.getOpenId());
						tplMessage.pushHead("").pushTail("").pushItem("first", member.getName() + "，您的服务已变更！")
								.pushItem("keyword1", oldVipStr).pushItem("keyword2", newVipStr)
								.pushItem("keyword3", DateUtils.getDateStr(member.getExpireDate(), "yyyy-MM-dd"))
								.pushItem("remark", "若需帮助请联系客服。");
						TmplApi tmplApi = new TmplApi(weixinProxy.getTokenManager());
						String sendResult = tmplApi.sendTmplMessage(tplMessage);
						System.out.println(
								"消息模板【" + WeiXinConfig.WEIXIN_LEVEL_CHANGE_TEMPLATE_ID + "】发送消息返回结果：" + sendResult);
						logger.info("消息模板【" + WeiXinConfig.WEIXIN_LEVEL_CHANGE_TEMPLATE_ID + "】发送消息返回结果：" + sendResult);
					} catch (WeixinException e) {
						e.printStackTrace();
					}
				}
			}

			logger.info("微信支付回调通知----->支付成功。");
			return XmlStream.toXML(new XmlResult(Consts.SUCCESS, ""));
		} else {
			String orderNo = wxOrder.getOutTradeNo();
			String orderType = orderNo.substring(0, 1);
			if (SoftOrder.ORDER_NO_START.equals(orderType)) {
				SoftOrder softOrder = softOrderService.findByOrderNo(orderNo);
				if (SoftOrder.STATUS_NOT_PAY != softOrder.getStatus()) {
					logger.error("订单【" + softOrder.getOrderNo() + "】未处于未支付状态！");
					return null;
				}
				softOrderService.executeSavePaymentRecord(softOrder, "", PaymentRecord.STATUS_FAIL,
						wxOrder.getReturnCode(), wxOrder.getReturnMsg());
			}
			logger.info("微信支付回调通知----->微信支付失败,错误信息..." + wxOrder.getReturnCode() + "," + wxOrder.getReturnMsg());
			return XmlStream.toXML(new XmlResult(Consts.FAIL, "支付失败"));
		}
	}

}
